package cn.charlotte.pit.commands.admin;


import cn.charlotte.pit.ThePit;
import cn.charlotte.pit.commands.PitCommands;
import cn.charlotte.pit.config.NewConfiguration;
import cn.charlotte.pit.config.PitConfig;
import cn.charlotte.pit.data.PlayerProfile;
import cn.charlotte.pit.npc.AbstractPitNPC;
import cn.charlotte.pit.npc.NpcFactory;
import cn.charlotte.pit.util.chat.CC;
import cn.charlotte.pit.util.chat.ChatComponentBuilder;
import cn.charlotte.pit.util.configuration.annotations.ConfigData;
import cn.charlotte.pit.util.configuration.annotations.ConfigSerializer;
import cn.charlotte.pit.util.configuration.serializer.LocationSerializer;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.*;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;

import java.lang.reflect.Field;
import java.util.Collections;

@CommandAlias("thepitsetup|setup|pitsetup")
@CommandPermission("pit.admin")
public class Setup extends BaseCommand {
    private final PitCommands pitCommands;

    public Setup(PitCommands pitCommands) {
        this.pitCommands = pitCommands;
    }



    @Subcommand("edit")
    public void onChangeEdit(Player player) {
        PlayerProfile profile = PlayerProfile.getPlayerProfileByUuid(player.getUniqueId());
        profile.setEditingMode(!profile.isEditingMode());
        if (profile.isEditingMode()) {
            player.sendMessage(CC.translate("&a你现在可以自由破坏方块"));
        } else {
            player.sendMessage(CC.translate("&c你关闭了自由破坏方块"));
        }
    }

    @Subcommand("punchY")
    @CommandCompletion("击飞高度|支持小数|默认4.0|4.0")
    public void punchY(Player player, String punchY) {
        double parsed = Double.parseDouble(punchY);

        YamlConfiguration config = NewConfiguration.getConfig();
        config.set("punch_y", parsed);
        NewConfiguration.save();

        player.sendMessage("ok");
    }

    @Subcommand("locs")
    @CommandCompletion("") //TODO 补全
    public void setLocCurrency(Player player, String field) {
        try {
            for (Field declaredField : PitConfig.class.getDeclaredFields()) {
                ConfigSerializer annotation = declaredField.getAnnotation(ConfigSerializer.class);
                if (annotation == null) {
                    break;
                }
                if (annotation.serializer() == LocationSerializer.class) {
                    ConfigData fieldAnnotation = declaredField.getAnnotation(ConfigData.class);
                    if (fieldAnnotation == null) {
                        break;
                    }
                    if (fieldAnnotation.path().equalsIgnoreCase(field)) {
                        declaredField.setAccessible(true);
                        declaredField.set(ThePit.getInstance().getPitConfig(), player.getLocation());
                        ThePit.getInstance().getPitConfig().save();
                        player.sendMessage(CC.translate("&a设置成功"));
                        return;
                    }
                }
            }
            player.sendMessage(CC.translate("&c没有找到"));
        } catch (Exception e) {
            e.printStackTrace();
            player.sendMessage(CC.translate("&c设置失败，请查看报错"));
        }
    }

    @Subcommand("addSpawn")
    public void addSpawn(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .getSpawnLocations()
                .add(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        int num = ThePit.getInstance()
                .getPitConfig()
                .getSpawnLocations()
                .size();

        player.sendMessage(CC.translate("&aSuccessfully!its " + num + "th spawnLocation"));
    }

    @Subcommand("getLocation")
    public void getLocation(Player player) {
        Location location = player.getLocation();
        player.sendMessage(new ChatComponentBuilder(location.toString())
                .setCurrentClickEvent(net.kyori.adventure.text.event.ClickEvent.suggestCommand(location.toString()))
                .build());
        player.sendMessage("§a设置成功！");
    }

    @Subcommand("npc keeper")
    public void setKeeperLocation(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setKeeperNpcLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage(CC.translate("&aSuccessfully!"));
    }

    @Subcommand("npc mail")
    public void setMailLocation(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setMailNpcLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage(CC.translate("&aSuccessfully!"));
    }

    @Subcommand("npc genesisDemon")
    public void setGenesisDemonLocation(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setGenesisDemonNpcLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage(CC.translate("&aSuccessfully!"));
    }

    @Subcommand("npc genesisAngel")
    public void setGenesisAngelLocation(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setGenesisAngelNpcLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage(CC.translate("&aSuccessfully!"));
    }

    @Subcommand("npc shop")
    public void setShopNpc(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setShopNpcLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage(CC.translate("&aSuccessfully!"));
    }

    @Subcommand("npc quest")
    public void setQuestNpc(Player player) {
        PitConfig pitConfig = ThePit.getInstance()
                .getPitConfig();
        pitConfig
                .setQuestNpcLocation(player.getLocation());
        pitConfig.save();
    }

    @Subcommand("npc perk")
    public void setPerkNpc(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setPerkNpcLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage(CC.translate("&aSuccessfully!"));
    }

    @Subcommand("npc leader")
    public void setLeaderNpc(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setLeaderBoardNpcLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage(CC.translate("&aSuccessfully!"));
    }

    @Subcommand("npc hamburger")
    public void setHamburgerNpc(Player player, String value) {
        if (value.equalsIgnoreCase("a")) {
            final PitConfig config = ThePit.getInstance()
                    .getPitConfig();
            config.getHamburgerNpcLocA()
                    .add(player.getLocation());
            config.save();

            player.sendMessage("Now: " + config.getHamburgerNpcLocA().size());
        }
    }

    @Subcommand("npc hamburgerClear")
    public void hamClearNpcLocations(Player player, String value) {
        if (value.equalsIgnoreCase("a")) {
            final PitConfig config = ThePit.getInstance()
                    .getPitConfig();
            config.getHamburgerNpcLocA().clear();
            config.save();
            player.sendMessage("ok");
        }
    }

    @Subcommand("npc prestige")
    public void setPrestigeNpc(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setPrestigeNpcLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage(CC.translate("&aSuccessfully!"));
    }

    @Subcommand("npc status")
    public void setStatusNpc(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setStatusNpcLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage(CC.translate("&aSuccessfully!"));
    }

    @Subcommand("holo spawn")
    public void setSpawnHologramLocation(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setHologramLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();
        player.sendMessage("§a设置成功！");
    }

    @Subcommand("holo enchant")
    public void setMythicHologram(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setMythicHologram(player.getLocation());
        ThePit.getInstance()
                .getPitConfig()
                .save();
        player.sendMessage("§a设置成功！");
    }

    @Subcommand("holo enderchest")
    public void setChestHologram(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setChestHologram(player.getLocation());
        ThePit.getInstance()
                .getPitConfig()
                .save();
        player.sendMessage("§a设置成功！");
    }

    @Subcommand("holo leader")
    public void setLeaderBoardHologram(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setLeaderBoardHologram(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();
        player.sendMessage("§a设置成功！");
    }

    @Subcommand("holo helper")
    public void setHelperHologram(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setHelperHologramLocation(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();
        player.sendMessage("§a设置成功！");
    }

    @Subcommand("pitLoc")
    @CommandCompletion("loc1|loc2")
    public void setPitLoc(Player player, String type) {
        if (type.equalsIgnoreCase("loc1")) {
            ThePit.getInstance().getPitConfig().setPitLocA(player.getLocation());
            ThePit.getInstance().getPitConfig().save();
        } else if (type.equalsIgnoreCase("loc2")) {
            ThePit.getInstance().getPitConfig().setPitLocB(player.getLocation());
            ThePit.getInstance().getPitConfig().save();
        }
    }

    @Subcommand("setkothloc")
    public void setKothLoc(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .getKothLocs()
                .add(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();
        player.sendMessage("§a设置成功！");
    }

    @Subcommand("setSpireFloor")
    public void spireFloorLocations(Player player) {
        try {
            final PitConfig config = ThePit.getInstance()
                    .getPitConfig();
            config.getSpireFloorLoc()
                    .add(player.getLocation());
            config.save();

            player.sendMessage("Now: " + config.getSpireFloorLoc().size());
        } catch (Exception e) {
            CC.printError(player, e);
        }
    }

    @Subcommand("setSpireSpawn")
    public void spireSpawn(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setSpireLoc(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();
    }

    @Subcommand("reloadnpc")
    private void reloadNpc(CommandSender sender) {
        for (AbstractPitNPC npc : NpcFactory.getPitNpc()) {
            npc.getNpc().spawn(npc.getNpcSpawnLocation());
        }
        sender.sendMessage("ok");
    }

    @Subcommand("enchanttable")
    private void onSetEnchantTable(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setEnchantLocation(player.getTargetBlock(Collections.singleton(Material.ENCHANTING_TABLE), 100).getLocation());

        ThePit.getInstance()
                .saveConfig();

        player.sendMessage(CC.translate("&aSave!"));
    }

    @Subcommand("seteggloc")
    private void setEggLoc(Player player) {
        ThePit.getInstance()
                .getPitConfig()
                .setEggLoc(player.getLocation());

        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage(CC.translate("&aSuccessfully!"));
    }

    @Subcommand("genesis addAngelSpawns")
    public void addAngelSpawns(Player player) {
        ThePit.getInstance().getPitConfig()
                .getAngelSpawns()
                .add(player.getLocation().clone());
        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage("ok");
    }

    @Subcommand("genesis addDemonSpawns")
    public void addDemonSpawns(Player player) {
        ThePit.getInstance().getPitConfig()
                .getDemonSpawns()
                .add(player.getLocation().clone());
        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage("ok");
    }

    @Subcommand("addPackagePoint")
    public void addPackagePoint(Player player) {
        ThePit.getInstance().getPitConfig()
                .getPackageLocations()
                .add(player.getLocation().clone());
        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage("ok");
    }

    @Subcommand("addSewersPoint")
    public void addSewersPoint(Player player) {
        ThePit.getInstance().getPitConfig()
                .getSewersChestsLocations()
                .add(player.getLocation().clone());
        ThePit.getInstance()
                .getPitConfig()
                .save();

        player.sendMessage("ok");
    }

    @Subcommand("addSquadsLoc")
    public void squadsAddLocation(Player player) {
        ThePit.getInstance().getPitConfig().getSquadsLocations().add(player.getLocation());
        ThePit.getInstance().getPitConfig().save();

        player.sendMessage("ok");
    }

    @Subcommand("addBlockHeadLoc")
    public void bhAddLocation(Player player) {
        ThePit.getInstance().getPitConfig().getBlockHeadLocations().add(player.getLocation());
        ThePit.getInstance().getPitConfig().save();

        player.sendMessage("ok");
    }





}
